package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import design.onekey.base.*;
import design.onekey.constant.enums.DelFlagEnum;
import design.onekey.constant.enums.RedisPerfixEnum;
import design.onekey.constant.StatusCode;
import design.onekey.exception.BizException;
import design.onekey.mapper.SysCodeTypeMapper;
import design.onekey.model.SysCodeType;
import design.onekey.model.SysCodeValue;
import design.onekey.model.dto.UserInfoDto;
import design.onekey.model.dto.SysCodeValueDto;
import design.onekey.service.ISysCodeTypeService;
import design.onekey.util.MessageUtil;
import design.onekey.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * @author
 * @version V1.0
 * @Description: SysCodeType服务实现
 * @date 2020-06-05 04:02:20
 */
@Service
public class SysCodeTypeServiceImpl extends ServiceImpl<SysCodeTypeMapper, SysCodeType> implements ISysCodeTypeService {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * @param @param model
     * @return BaseEntity
     * @throws
     * @Title: tablePagingQuery
     * @Description: 表格分页查询
     * @author
     */
    @Override
    public PageEntity tablePagingQuery(SysCodeType model) {
        PageEntity result = new PageEntity();
        model.setDelFlag(DelFlagEnum.UNDEL.getCode());
        com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
        List<SysCodeType> list = this.baseMapper.searchDataLike(model);
        result.setData(list);
        result.setTotal(page.getTotal());
        result.setCurrentPage(model.getCurrentPage());
        result.setPageSize(model.getPageSize());
        return result;
    }


    /**
     * <p>Title: getDetail</p>
     * <p>Description: 获取详情</p>
     *
     * @param id
     * @return
     * @author
     */
    @Override
    public BaseEntity getDetail(Long id) {
        return this.getById(id);
    }

    /**
     * <p>Title: insert</p>
     * <p>Description: 新增数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity insert(SysCodeType model, UserInfoDto userInfoDto) {
        QueryWrapper<SysCodeType> queryWrapper = new QueryWrapper<SysCodeType>().eq("code_type", model.getCodeType()).eq("del_flag", DelFlagEnum.UNDEL.getCode());
        Function<QueryWrapper<SysCodeType>, Boolean> function = q -> this.baseMapper.selectCount(q) != 0;
        BaseEntity result = new BaseEntity();
        if (checkRepeat(queryWrapper, function)) {
            throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.check.exist", new String[]{"字典类别代码"}));
        }
        this.save(model);
        //新增成功,插入缓存
		try {
			redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode()+model.getCodeType(),new ArrayList<SysCodeValue>());
		} catch (Exception e) {
			//不成功不影响插入
			e.printStackTrace();
		}
		result.setStatusMsg(MessageUtil.getValue("info.insert"));
        return result;
    }

    /**
     * <p>Title: update</p>
     * <p>Description: 更新数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity update(SysCodeType model, UserInfoDto userInfoDto) {
        String codeType1 = this.baseMapper.selectById(model.getId()).getCodeType();

        QueryWrapper<SysCodeType> queryWrapper = new QueryWrapper<SysCodeType>().eq("code_type", model.getCodeType()).ne("id", model.getId()).
                eq("del_flag", DelFlagEnum.UNDEL.getCode());
        Function<QueryWrapper<SysCodeType>, Boolean> function = q -> this.baseMapper.selectCount(q) != 0;
        if (this.checkRepeat(queryWrapper, function)) {
            throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.check.exist", new String[]{"字典类别代码"}));
        }
        BaseEntity result = new BaseEntity();
        this.updateById(model);
        //更新缓存 如果codeType发生改变，否则不更新
		try {
			if (codeType1!=model.getCodeType()){
				//修改缓存,获取原来的name
				String codeType = this.baseMapper.selectById(model.getId()).getCodeType();
				//查询缓存的值
				List<SysCodeValue> sysCodeValues = (List<SysCodeValue>) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + codeType);
				//删除
				redisUtil.del(RedisPerfixEnum.SYSCODETYPE.getCode() + codeType);
				//重新插入
				redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode()+model.getCodeType(),sysCodeValues);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
        result.setStatusMsg(MessageUtil.getValue("info.update"));
        return result;
    }

    /**
     * <p>Title: delete</p>
     * <p>Description: 单条删除数据</p>
     *
     * @param model
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity delete(Long id) {
        SysCodeType sysCodeType = new SysCodeType();
        sysCodeType.setId(id);
        sysCodeType.setDelFlag(DelFlagEnum.DEL.getCode());
        this.updateById(sysCodeType);
        BaseEntity result = new BaseEntity();
		try {
			//查询codeType
			String codeType = this.baseMapper.selectById(id).getCodeType();
			//删除对应的缓存
			redisUtil.del(RedisPerfixEnum.SYSCODETYPE.getCode()+codeType);
		} catch (Exception e) {
			e.printStackTrace();
		}
		result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     * <p>Title: deleteBatch</p>
     * <p>Description: 批量删除数据</p>
     *
     * @param list
     * @return
     * @author
     */
    @Transactional
    @Override
    public BaseEntity deleteBatch(List<Long> ids) {
        List<SysCodeType> list = new ArrayList<SysCodeType>();
        for (int i = 0; i < ids.size(); i++) {
            SysCodeType sysCodeType = new SysCodeType();
            sysCodeType.setId(ids.get(i));
            sysCodeType.setDelFlag(DelFlagEnum.DEL.getCode());
            list.add(sysCodeType);
        }
        BaseEntity result = new BaseEntity();
        if (list != null && list.size() > 0) {
            this.updateBatchById(list);
        }
        list.forEach(p->{
			try {
				//查询codeType
				String codeType = this.baseMapper.selectById(p.getId()).getCodeType();
				//删除对应的缓存
				redisUtil.del(RedisPerfixEnum.SYSCODETYPE.getCode()+codeType);
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
        result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     * @Method loadAllTypeInfo
     * @Author zhangcheng
     * @Version 1.0
     * @Description 1代表初次加载 否则代表刷新
     * @Return com.baiyyy.yfz.base.BaseEntity
     * @Exception
     * @Date 2020-6-17 10:48
     */
    @Override
    public BaseEntity loadAllTypeInfo(String isFirst) {
        BaseEntity result = new BaseEntity();
        if (isFirst.equals("1")) {
            //判断是否初始化过initFlag
            String initTypeFlag = (String) redisUtil.get(RedisPerfixEnum.SYSCODETYPE.getCode() + "initFlag");
            if (StringUtil.isNotEmpty(initTypeFlag)) {
                return result;
            }
        }
        //查询一遍数据库。吧type和value查询出来
        List<SysCodeValueDto> sysCodeValueDtos = this.baseMapper.selectTypeWithValue();
        if (null != sysCodeValueDtos && sysCodeValueDtos.size() > 0) {
            sysCodeValueDtos.stream().forEach(
                    p -> {
                        //type+详情
                        redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + p.getCodeType(), p.getCodeValues());
                        p.getCodeValues().forEach(v -> {
                            //codeType+valueName
                            redisUtil.set(RedisPerfixEnum.SYSCODEVALUE.getCode() + v.getCodeType()+":"+v.getCodeValue(), v.getCodeValueName());
                            //codeType+codeTypeValue
//                            redisUtil.set(RedisPerfixEnum.SYSCODETYPEVALUE.getCode()+v.getCodeType()+v.getCodeValue(), v.getId());
                        });
                    }
            );
            redisUtil.set(RedisPerfixEnum.SYSCODETYPE.getCode() + "initFlag", "1");
        }
        return result;
    }
}
